// *#5239870*#
// *#7092463*#

package GPSTracker;

import javax.microedition.lcdui.*;
import javax.microedition.io.*;
import javax.microedition.io.file.*;
import java.util.*;
import java.io.*;
import sUtils.*;

/**
 *
 * @author thomas.s
 */
public class GPSTrackerView extends Canvas  {

     private static final String[] names =
     {  "GPS:",
        "File:",
        "time:",
        "Dist:",
        "Lat:" , 
        "Lon:",
        "Alt:", 
        "Mag:",  
        "Speed:",
        "v-max:", 
        "v-avg:", 
        "wait for signal...",
        };

    private String[] data;
    private Timer timer, capture;
    long lastUpdate;
    int speed;
    Image digit[];
    Image bg;
    int sx, sy, dx, dy, screenw, screenh, digitw, digith;
    int mx, my;
    long mTime;
    Display display;
    public boolean doublePressed, noUpdate;

    public GPSTrackerMenu menu;
    public GPSTrackerThread gpx;
    ScreenSaver saver;


    public void setActive()
    {
        if (display!=null) {
             display.setCurrent(this);
             display.flashBacklight(50);
        }
    }

    public GPSTrackerView (Display d, GPSTrackerThread g, GPSTrackerMenu m) {
        menu = m;
        gpx = g;
        this.setFullScreenMode(true);
        lastUpdate = 0;
        sx = sy = dx = dy = 0;
        speed = 0;
        data = new String[11];
        display = d;
        screenw = getWidth();
        screenh = getHeight();
        digitw = screenw;
        digith = (screenh)/3;
        doublePressed = false;

        bg = null;
        if ( !menu.bg_file.equals("") )
            {
                try {
                    FileConnection f = (FileConnection) Connector.open(menu.bg_file);
                    bg = Image.createImage(f.openDataInputStream());
                    f.close();
                }
                catch (IOException e) { bg = null;}
            }

        if (bg==null) try {
                FileConnection f = (FileConnection) Connector.open("file:///filesystem/gpstracker_bg.jpg",Connector.READ);
                bg = Image.createImage(f.openInputStream());
            } catch (Exception e) { bg=null;}

        //if (bg==null) try { bg = Image.createImage ( "/ripplebg.jpg" ); } catch (IOException e) { bg = null; }

        digit = new Image[10];
        updateDigits();

        data[0] = menu.getText("wait for signal...");
        timer = new Timer();
        timer.schedule(new updateTask(this), 100, 100 );

   //     capture = new Timer();
     //   capture.schedule(new captureTask(this), 100, 3000 );
    }

    void updateDigits() {
        noUpdate=true;
        synchronized(this)
        {
            Image img = null;
            if ( !menu.digit_file.equals("") )
            {
                try {
                    FileConnection f = (FileConnection) Connector.open(menu.digit_file,Connector.READ);
                    img = Image.createImage(f.openDataInputStream());
                    f.close();
                }
                catch (Exception e) { img = null;}
            }

            if (img==null) try {
                FileConnection f = (FileConnection) Connector.open("file:///filesystem/gpstracker_digits.gif",Connector.READ);
                img = Image.createImage(f.openInputStream());
            } catch (Exception e) { img=null;}

            if (img==null) try { img = Image.createImage("/gpstracker_digits.gif"); } catch (IOException e) { img = null;}
            if (img==null) return;

            int imageWidth = img.getWidth();
            int imageHeight = img.getHeight();
            digitw = (int)(screenw*menu.digit_size)/100;
            digith = (int)((screenh*menu.digit_size)/100)/3;

            int[] rgb = new int[imageWidth * imageHeight];

            img.getRGB(rgb, 0, imageWidth, 0, 0, imageWidth, imageHeight);

            int sw = imageWidth/10;
            int sh = imageHeight;
            int col, fillcolor=menu.digit_color;
            for ( int i=0; i<10;  i++ )
            {
                int [] dst = new int[digith*digitw];
                if ( menu.digit_mirror==1 )
                {
                    for ( int x=0; x<digith; x++ ) for ( int y=0; y<digitw; y++)
                        {
                            col = rgb[(x*sw)/digith+i*sw+((y*sh)/digitw*imageWidth)];
                            col = ((col&0xff00)<<16)|fillcolor;
                            dst[(y+x*digitw)] = col;
                        }
                }
                else
                {
                    for ( int x=0; x<digith; x++ ) for ( int y=0; y<digitw; y++)
                        {
                            col = rgb[(x*sw)/digith+i*sw+((y*sh)/digitw*imageWidth)];
                            col = ((col&0xff00)<<16)|fillcolor;
                            dst[((digitw-y-1)+x*digitw)] = col;
                        }
                }
                digit[i] = Image.createRGBImage(dst, digitw, digith, true);
            }
        }
        noUpdate=false;
    }
/*
    class captureTask extends TimerTask {
        private GPSTrackerView canvas;
        private int shot = 2000;

        captureTask( GPSTrackerView c ){ canvas = c; }
        public void run() {
            Image img = Image.createImage(480,800);
            canvas.paint(img.getGraphics());
            int rgb[] = new int[480*800];
            byte rgbb[] = new byte[480*800*3];
            img.getRGB(rgb, 0,480,0,0,480,800);
            shot++;
            for ( int i=0,j=0; i<480*800; i++ )
            {   int col=rgb[i];
                for ( int n=0; n<3; n++ ) { rgbb[j++]=(byte)(col&0xff); col>>=8; }
            }
            try{
                FileConnection f = (FileConnection) Connector.open("file:///mmc/Screenshot" + shot +".raw");
                f.create();
                f.openDataOutputStream().write(rgbb, 0, 480*800*3);
                f.close();
            } catch( Exception e ) { }

        }
    }
*/
    class updateTask extends TimerTask {
        private GPSTrackerView canvas;
        int counter=0;
        updateTask( GPSTrackerView c ){  canvas = c;  }
        public void run()
        {
            counter++;
            boolean ok = false;
            if (canvas.saver==null || (counter&1)!=0 ) ok = updateLocation();
            if (!canvas.noUpdate) {
                ok |= updateScroll();
                if (ok) canvas.repaint(); }
        }
    }

    void paintDigit2( Graphics g, int x, int y, int d )
    {
        synchronized(this)
        {
        if (digit!=null && d>=0) g.drawImage(digit[d%10], x, y, 0);
        }
    }

    protected void paintDigit( Graphics g, int x, int y, int w, int h, int th, int d )
    {
        int x0 = x;
        int x1 = x+w-th;
        int y0 = y;
        int y1 = y+h/2-th/2;
        int y2 = y+h-th;
        int D=0;
        switch (d)
        {
            case 0:  D=1+2+4+16+32+64; break;
            case 1:  D=4+32; break;
            case 2:  D=1+4+8+16+64; break;
            case 3:  D=1+4+8+32+64; break;
            case 4:  D=4+2+8+32; break;
            case 5:  D=1+2+8+32+64; break;
            case 6:  D=1+2+8+16+32+64; break;
            case 7:  D=1+4+32; break;
            case 8:  D=1+2+4+8+16+32+64; break;
            case 9:  D=1+2+4+8+32+64; break;
        }
        int R = (th*2)/3;
        int T = th/3;
        if ((D&1)>0) g.fillRoundRect(x0+T,y0,w-T*2,th,R,R);
        if ((D&2)>0) g.fillRoundRect(x0,y0+T,th,h/2-T*2,R,R);
        if ((D&4)>0) g.fillRoundRect(x1,y0+T,th,h/2-T*2,R,R);
        if ((D&8)>0) g.fillRoundRect(x0+T,y1,w-T*2,th,R,R);
        if ((D&16)>0) g.fillRoundRect(x0,y1+T,th,h/2-T*2,R,R);
        if ((D&32)>0) g.fillRoundRect(x1,y1+T,th,h/2-T*2,R,R);
        if ((D&64)>0) g.fillRoundRect(x0+T,y2,w-T*2,th,R,R);

    }

    protected void paint (Graphics g) {

        int w = getWidth ();
        int h = getHeight ();
        int y = 60;
        int th = screenh/20;
        
        // Fill the background
        
        if (bg!=null) {
            g.drawImage(bg, sx-screenw, sy, 0);
            if (screenw>240) g.drawImage(bg, sx, sy,0 );
        } else {
            g.setColor (0);
            g.fillRect (0, 0, w, h);
        }
        g.setFont( Font.getFont( Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_SMALL ) );
        if (lastUpdate>0) g.setColor(0x202028); else g.setColor (0x282020);
        g.drawString("http://www.handy-faq.de",sx+2,2,0);

        g.setColor( menu.digit_color );
        g.drawArc(w-50,5,40,40,0,360);
        g.fillArc(w-40,15,21,21,0,360);

        if (sx>0)
        {
            if (speed>=100) paintDigit2(g,sx-screenw,sy+0,(speed/100)%10);
            if (speed>=10) paintDigit2(g,sx-screenw,sy+digith,(speed/10)%10);
            paintDigit2(g,sx-screenw,sy+digith*2,speed%10);
        }
        if (sx<screenw)
        {
            g.setFont( Font.getFont( Font.FACE_MONOSPACE, Font.STYLE_PLAIN, th>30 ? Font.SIZE_LARGE : Font.SIZE_MEDIUM) );
            g.setColor( menu.digit_color );
            for (int i=0; i<data.length; i++ )
            {
                if (menu.display_gps==1 || i<3 || i>6 ) {
                    g.drawString ( menu.getText(names[i]), sx+155, sy+y, Graphics.RIGHT | Graphics.TOP);
                    if (data[i]!=null) g.drawString (data[i], sx+155, sy+y, Graphics.LEFT | Graphics.TOP);
                    y+=th;
                }
            }

            g.setColor( menu.digit_color );
            int digith = screenh/3;
            int digitw = screenw/3;
            int dd = screenw/16;
            if (speed>=100) paintDigit(g,sx+0,sy+h-digith,digitw-10,digith,dd,(speed/100)%10);
            if (speed>=10) paintDigit(g,sx+digitw,sy+h-digith,digitw-10,digith,dd,(speed/10)%10);
            paintDigit(g,sx+digitw*2,sy+h-digith,digitw-10,digith,dd,speed%10);
        }
    }

    public boolean updateScroll()
    {
        if (dx==0 && dy==0) return false;
        if (dx>0 && sx<screenw) sx+=dx;
        if (dx<0 && sx>0) sx+=dx;
        if (dy!=0) dy=0;
        if (dx!=0 && sx>=screenw) { sx=screenw; dx=0; }
        if (dx!=0 && sx<0) { sx=0; dx=0; }
        return true;
    }
    
    public boolean updateLocation()
    {
        if (menu.langUpdated()) data[0] = menu.getText("wait for signal...");
        if (!gpx.locatorOk()) data[0] = menu.getText("wait for signal..."); else
        if ( gpx.updateLocator())
        {
            speed = (int)(gpx.speed*menu.speed_factor);
            data[0] = "ok";
            data[1] = gpx.recording() ? gpx.trackName : "";
            data[2] = Strings.toStr( (gpx.time/60000), 3, 0, ' ', "", ":") + Strings.toStr( (gpx.time/1000)%60, 2, 0, '0', "", "");
            data[3] = Strings.toStr( gpx.dist*menu.dist_factor, 6, 3, ' ',"",menu.dist_name);
            data[4] = Strings.getGPS_GMS( gpx.lat, 'N', 'S' ); //StringHelper.toStr( gpx.lat, 4, 7, ' ', "","°");
            data[5] = Strings.getGPS_GMS( gpx.lon, 'E', 'W' ); //StringHelper.toStr( gpx.lon, 4, 7, ' ', "","°");
            if (gpx.alt!=0) data[6] = Strings.toStr( gpx.alt-menu.alt_corr, 4, 1, ' ', "","m")+Strings.toStr( gpx.altsum, 1, 1, ' ', " (+","m)");
            if (gpx.course!=0) data[7] = Strings.toStr( gpx.course, 4, 1, ' ', "","°") + "  " + gpx.courseText;
            data[8] = Strings.toStr( gpx.speed*menu.speed_factor, 4, 1, ' ', "",menu.speed_name);
            data[9] = Strings.toStr( gpx.speedmax*menu.speed_factor, 4, 1, ' ', "", menu.speed_name);
            data[10] = Strings.toStr( gpx.speeds/gpx.speedn*menu.speed_factor, 4, 1, ' ', "", menu.speed_name);

           // data[8] = gpx.info;
           // data[9] = gpx.nmea;
            return true;
        }
        return false;
    }

    public void pointerPressed( int x, int y )
    {
        if ( x>getWidth()-50 && y<50 )
        {
            saver = new ScreenSaver(this,gpx,menu);
            display.setCurrent(saver);
            return;
        }
        display.vibrate(20);
        if ((System.currentTimeMillis() - mTime)<240) doublePressed=true;
        mx=x; my=y; mTime = System.currentTimeMillis(); dx=0;
    }

    public void pointerDragged( int x, int y )
    {
        dx+=(x-mx); mx=x;
    }

    public void pointerReleased( int x, int y )
    {
        if (doublePressed && dx==0 && dy==0 && menu!=null) menu.setActive();
        doublePressed=false;
    }

    public void keyPressed( int key )
    {
        if ( key==-10) { if (menu!=null) menu.setActive(); }
        if (key==-3) { sx=screenw; repaint(); }
        if (key==-4) { sx=0; repaint(); }
    }

    public void vibrate()
    {
        display.vibrate(10);
    }

    public void endScreenSaver()
    {
        display.setCurrent(this);
        saver = null;
    }

}
